package cn.org.mrliu.ssm.common.service.impl;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.github.pagehelper.PageHelper;

import cn.org.mrliu.ssm.common.exception.AffectedRowZeroException;
import cn.org.mrliu.ssm.common.mapper.BaseMapper;
import cn.org.mrliu.ssm.common.model.BaseModel;
import cn.org.mrliu.ssm.common.service.BaseService;
import cn.org.mrliu.ssm.common.web.vo.QueryParam;
import cn.org.mrliu.ssm.constant.Global;
import cn.org.mrliu.ssm.util.CollectionUtil;
import cn.org.mrliu.ssm.util.OrderBy;
import cn.org.mrliu.ssm.util.Pagination;
import cn.org.mrliu.ssm.util.cache.Cache;
import org.springframework.cache.annotation.Cacheable;

public abstract class BaseServiceSupport<Model extends BaseModel> implements BaseService<Model> {
	@SuppressWarnings("rawtypes")
	protected abstract BaseMapper getBaseMapper();

	@SuppressWarnings("unchecked")
	@Override
	@Cache("5")
	public Integer saveModel(Model model) throws Exception {
		getBaseMapper().save(model);
		return model.getId();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public Integer saveSelectiveModel(Model model) throws Exception {
		getBaseMapper().saveSelective(model);
		return model.getId();
	}

	@SuppressWarnings("unchecked")
	@Override
	public void updateModel(Model model) throws Exception {
		Integer result = getBaseMapper().update(model);
		if (result<1) {
			throw new AffectedRowZeroException("修改的记录不存在");
		}
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public void updateSelectiveModel(Model model) throws Exception {
		getBaseMapper().updateSelective(model);
	}

	@Override
	public Integer saveOrUpdateModel(Model model) throws Exception {
		Integer id = model.getId();
		if (id == null) {
			return saveModel(model);
		} else {
			updateModel(model);
		}
		return id;
	}

	@Override
	public void deleteModel(Integer id) throws Exception {
		Integer result = getBaseMapper().delete(id);
		if (result<1) {
			throw new AffectedRowZeroException("修改的记录不存在");
		}
		
	}

	@SuppressWarnings("unchecked")
	@Override
	public Model getModel(Integer id) throws Exception {
		return (Model) getBaseMapper().get(id);
	}

	@Override
	public List<Integer> getModelIds() throws Exception {
		return getModelIds(null);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Integer> getModelIds(Object param) throws Exception {
		return getBaseMapper().getIds(param);
	}

	@Override
	public void batchSaveModel(Collection<Model> collection) throws Exception {
		if (collection == null || collection.size() == 0) {
			return;
		}
		// 获取到集合大小
		int size = collection.size();
		// 参数map
		Map<String, Object> param = new HashMap<>();
		param.put("columns", new String[]{"name"});
		// 批量执行间隔,如果集合大小 < 间隔,则直接全部批量执行,否则:将集合拆分成多个部分,再批量操作,提高效率
		int interval = Global.BATCH_SAVE_INTERVAL;
		if (size < interval) {
			param.put("collection", collection);
			getBaseMapper().batchSave(param);
		} else {
			// 获取到集合的部分数据
			Object[] objects = CollectionUtil.split(collection, interval);
			for (Object object : objects) {
				param.put("collection", object);
				getBaseMapper().batchSave(param);
			}
		}
	}

	@Override
	public void batchSaveModel(Model[] array) throws Exception {
		batchSaveModel(Arrays.asList(array));
	}

	@Override
	public void batchUpdateModel(Model model, Collection<?> ids) throws Exception {
		if (ids == null || ids.size() == 0) {
			return;
		}
		// 获取到集合大小
		int size = ids.size();
		// 参数map
		Map<String, Object> param = new HashMap<>();
		param.put("object", model);
		// 批量执行间隔,如果集合大小 < 间隔,则直接全部批量执行,否则:将集合拆分成多个部分,再批量操作,提高效率
		int interval = Global.BATCH_UPDATE_INTERVAL;
		if (size < interval) {
			param.put("ids", ids);
			getBaseMapper().batchUpdate(param);
		} else {
			// 获取到集合的部分数据
			Object[] objects = CollectionUtil.split(ids, interval);
			for (Object object : objects) {
				param.put("ids", object);
				getBaseMapper().batchUpdate(param);
			}
		}
	}

	@Override
	public void batchUpdateModel(Model model, Object[] ids) throws Exception {
		batchUpdateModel(model, Arrays.asList(ids));
	}

	@Override
	public void batchDeleteModel(Collection<?> ids) throws Exception {
		if (ids == null || ids.size() == 0) {
			return;
		}
		// 获取到集合大小
		int size = ids.size();
		// 参数map
		Map<String, Object> param = new HashMap<>();
		// 批量执行间隔,如果集合大小 < 间隔,则直接全部批量执行,否则:将集合拆分成多个部分,再批量操作,提高效率
		int interval = Global.BATCH_DELETE_INTERVAL;
		if (size < interval) {
			param.put("ids", ids);
			getBaseMapper().batchDelete(param);
		} else {
			// 获取到集合的部分数据
			Object[] objects = CollectionUtil.split(ids, interval);
			for (Object object : objects) {
				param.put("ids", object);
				getBaseMapper().batchDelete(param);
			}
		}
	}

	@Override
	public void batchDeleteModel(Object[] ids) throws Exception {
		batchDeleteModel(Arrays.asList(ids));
	}

	@Override
	public List<?> getModelList() throws Exception {
		return getModelList(null);
	}

	@Override
	public List<?> getModelList(Object param) throws Exception {
		return getBaseMapper().getList(param);
	}

	@Override
	public Integer getModelCount() throws Exception {
		return getModelCount(null);
	}

	@Override
	public Integer getModelCount(Object param) throws Exception {
		return getBaseMapper().getCount(param);
	}

	@Override
	public boolean isExist(String name) throws Exception {
		Map<String, Object> map = new HashMap<>();
		map.put("name", name);
		return getBaseMapper().getCount(map) > 0;
	}

	@Override
	public boolean isExist(Model model) throws Exception {
		return getBaseMapper().getCount(model) > 0;
	}

	@Override
	public Pagination getPagination(Integer pageIndex, Integer pageSize) throws Exception {
		return getPagination(pageIndex, pageSize, null, null);
	}

	@Override
	public Pagination getPagination(Integer pageIndex, Integer pageSize, Object param) throws Exception {
		return getPagination(pageIndex, pageSize, param, null);
	}

	@Override
	public Pagination getPagination(Integer pageIndex, Integer pageSize, Object param, String orderBy)
			throws Exception {
		return getPagination(pageIndex, pageSize, param, orderBy, null);
	}

	@Override
	public Pagination getPagination(Integer pageIndex, Integer pageSize, Object param, String orderColumn,
			OrderBy orderBy) throws Exception {
		String orderByString = orderColumn;
		if (orderBy != null) {
			orderByString += " " + orderBy.value();
		}
		PageHelper.startPage(pageIndex, pageSize, orderByString);
		return new Pagination(getBaseMapper().getPageList(param));
	}

	@Override
	public Pagination getPagination(QueryParam queryParam) throws Exception {
		return getPagination(queryParam, null);
	}

	@Override
//	@Cacheable(value = "defaultCache",key = "target+'_'+methodName+'_'+args")
	@Cacheable(value = "defaultCache")
	public Pagination getPagination(QueryParam queryParam, Map<String, Object> param) throws Exception {
		// 如果keyword不为空,则添加到param中,如果param中也有keyword,将以param中的keyword为准
		String keyword = queryParam.getKeyword();
		if (keyword != null) {
			boolean isExistKeyWord = false;
			if (param == null) {
				param = new HashMap<>();
			} else {
				isExistKeyWord = param.containsKey("keyword");
			}
			if (!isExistKeyWord) {
				param.put("keyword", keyword);
			}
		}
		return getPagination(queryParam.getPageIndex(), queryParam.getPageSize(), param, queryParam.getOrderColumn(),
				OrderBy.getOrderBy(queryParam.getOrderBy()));
	}
}
